package com.shunda.ysdgj.manager.service.impl.goods;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseService;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.shunda.ysdgj.common.exception.CustomException;
import com.shunda.ysdgj.common.util.ValidateUtil;
import com.shunda.ysdgj.manager.mapper.goods.GoodsSpuMapper;
import com.shunda.ysdgj.manager.service.goods.GoodsSkuService;
import com.shunda.ysdgj.manager.service.goods.GoodsSpuService;
import com.shunda.ysdgj.manager.service.system.SysUserService;
import com.shunda.ysdgj.model.dto.base.IdsDto;
import com.shunda.ysdgj.model.dto.goods.GoodsSpuFindDto;
import com.shunda.ysdgj.model.entity.goods.GoodsBrand;
import com.shunda.ysdgj.model.entity.goods.GoodsSpecCategory;
import com.shunda.ysdgj.model.entity.goods.GoodsSpu;
import com.shunda.ysdgj.model.entity.system.SysUser;
import com.shunda.ysdgj.model.vo.ResultCodeEnum;
import com.shunda.ysdgj.model.vo.goods.GoodsSpuSelectVo;
import com.shunda.ysdgj.model.vo.goods.GoodsSpuVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class GoodsSpuServiceImpl
        extends MPJBaseServiceImpl<GoodsSpuMapper, GoodsSpu>
        implements GoodsSpuService, MPJBaseService<GoodsSpu> {

    private final SysUserService sysUserService;
    private final GoodsSkuService goodsSkuService;

    public GoodsSpuSelectVo getSelectVoById(Long id) {
        MPJLambdaWrapper<GoodsSpu> baseWrapper = JoinWrappers
                .lambda(GoodsSpu.class)
                .select(GoodsSpu::getId, GoodsSpu::getSpuTitle)
                .eq(GoodsSpu::getId, id)
                .eq(GoodsSpu::getSpuSaleable, 1)
                .eq(GoodsSpu::getSpuValid, 1);
        return getBaseMapper().selectJoinOne(GoodsSpuSelectVo.class, baseWrapper);
    }

    public Map<String, Long> getSpecCategoryIdsById(Long id) {
        LambdaQueryWrapper<GoodsSpu> baseWrapper = new LambdaQueryWrapper<>();
        baseWrapper
                .select(GoodsSpu::getSpuSpecCategoryId, GoodsSpu::getSpuSpecNoSearchCategoryId)
                .eq(GoodsSpu::getId, id);
        Map<String, Object> map = getBaseMapper().selectMaps(baseWrapper).get(0);
        Map<String, Long> categoryIdsMap = new HashMap<>();
        categoryIdsMap.put("searchCategoryId", Long.valueOf(map.get("spu_spec_category_id").toString()));
        categoryIdsMap.put("noSearchCategoryId", Long.valueOf(map.get("spu_spec_no_search_category_id").toString()));
        return categoryIdsMap;
    }

    public List<GoodsSpuSelectVo> findByTitle(String title) {
        if (StrUtil.isEmpty(title)) {
            return new ArrayList<>();
        }
        MPJLambdaWrapper<GoodsSpu> baseWrapper = JoinWrappers
                .lambda(GoodsSpu.class)
                .select(GoodsSpu::getId, GoodsSpu::getSpuTitle)
                .like(GoodsSpu::getSpuTitle, title);
        return getBaseMapper().selectJoinList(GoodsSpuSelectVo.class, baseWrapper);
    }

    public IPage<GoodsSpuVo> findByPage(GoodsSpuFindDto goodsSpuFindDto) {
        if (ValidateUtil.isNotLong(goodsSpuFindDto.getCurrent())) {
            goodsSpuFindDto.setCurrent(1L);
        }
        if (ValidateUtil.isNotLong(goodsSpuFindDto.getSize())) {
            goodsSpuFindDto.setSize(10L);
        }
        MPJLambdaWrapper<GoodsSpu> baseWrapper = JoinWrappers
                .lambda(GoodsSpu.class)
                .select(
                        GoodsSpu::getId, GoodsSpu::getSpuTitle,
                        GoodsSpu::getSpuCategoryId, GoodsSpu::getSpuBrandId,
                        GoodsSpu::getSpuSpecCategoryId, GoodsSpu::getSpuImages,
                        GoodsSpu::getSpuSpecNoSearchCategoryId,
                        GoodsSpu::getSpuSaleable, GoodsSpu::getSpuValid,
                        GoodsSpu::getCreated, GoodsSpu::getUpdated, GoodsSpu::getVersion
                ).select(GoodsBrand::getBrandName)
                .select(GoodsSpecCategory::getSpecCategoryName)
                .select("c1.category_name as thirdCategoryName")
                .select("c2.category_name as secondCategoryName")
                .select("c3.category_name as firstCategoryName")
                .leftJoin(GoodsBrand.class, GoodsBrand::getId, GoodsSpu::getSpuBrandId)
                .leftJoin(GoodsSpecCategory.class, GoodsSpecCategory::getId, GoodsSpu::getSpuSpecCategoryId)
                .leftJoin("ysdgj_goods_category c1 on c1.id = t.spu_category_id")
                .leftJoin("ysdgj_goods_category c2 on c2.id = c1.parent_id")
                .leftJoin("ysdgj_goods_category c3 on c3.id = c2.parent_id");
        if (ValidateUtil.isNotBlank(goodsSpuFindDto.getSpuTitle())) {
            baseWrapper.like(GoodsSpu::getSpuTitle, goodsSpuFindDto.getSpuTitle());
        }
        if (ValidateUtil.isLong(goodsSpuFindDto.getSpuCategoryId())) {
            baseWrapper.eq(GoodsSpu::getSpuCategoryId, goodsSpuFindDto.getSpuCategoryId());
        }
        if (ValidateUtil.isLong(goodsSpuFindDto.getSpuBrandId())) {
            baseWrapper.eq(GoodsSpu::getSpuBrandId, goodsSpuFindDto.getSpuBrandId());
        }
        if (ValidateUtil.isInteger(goodsSpuFindDto.getSpuSaleable())) {
            baseWrapper.eq(GoodsSpu::getSpuSaleable, goodsSpuFindDto.getSpuSaleable());
        }
        if (ValidateUtil.isInteger(goodsSpuFindDto.getSpuValid())) {
            baseWrapper.eq(GoodsSpu::getSpuValid, goodsSpuFindDto.getSpuValid());
        }
        IPage<GoodsSpuVo> page = new Page<>(goodsSpuFindDto.getCurrent(), goodsSpuFindDto.getSize());
        return getBaseMapper().selectJoinPage(page, GoodsSpuVo.class, baseWrapper);
    }

    public boolean add(String token, GoodsSpu goodsSpu) {
        if (ValidateUtil.isBlank(goodsSpu.getSpuTitle())
                || ValidateUtil.isNotLong(goodsSpu.getSpuCategoryId())
                || ValidateUtil.isNotLong(goodsSpu.getSpuSpecNoSearchCategoryId())) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        SysUser sysUser = sysUserService.getUserInfo(token);
        goodsSpu.setId(null);
        goodsSpu.setSysUserId(sysUser.getId());
        goodsSpu.setShopId(sysUser.getShopId());
        return save(goodsSpu);
    }

    public boolean modify(GoodsSpu goodsSpu) {
        if (ValidateUtil.isNotLong(goodsSpu.getId())
                || ValidateUtil.isBlank(goodsSpu.getSpuTitle())
                || ValidateUtil.isNotLong(goodsSpu.getSpuCategoryId())
                || ValidateUtil.isNotLong(goodsSpu.getSpuSpecNoSearchCategoryId())) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        return updateById(goodsSpu);
    }

    public boolean modifySaleable(GoodsSpu goodsSpu) {
        if (ValidateUtil.isNotLong(goodsSpu.getId())
                || ValidateUtil.isNotInteger(goodsSpu.getSpuSaleable())) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        return updateById(goodsSpu);
    }

    public boolean modifyValid(GoodsSpu goodsSpu) {
        if (ValidateUtil.isNotLong(goodsSpu.getId())
                || ValidateUtil.isNotInteger(goodsSpu.getSpuValid())) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        return updateById(goodsSpu);
    }

    @Transactional
    public boolean deleteByIds(IdsDto idsDto) {
        List<Long> ids = idsDto.getIds();
        if (ids.isEmpty()) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        if (!removeByIds(ids)) {
           throw new CustomException(ResultCodeEnum.FAIL);
        }
        return goodsSkuService.deleteBySpuIds(idsDto.getIds());
    }

}
